﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WS.EKA.ServiceInterface;
using WS.EKA.DataAccess;
using WS.EKA.Model;
using WS.EKA.Utilities.Consts;
using System.Linq.Expressions;
using WS.EKA.Utilities;
using WS.EKA.Utilities.Helpers;

namespace WS.EKA.ServiceImpl
{
    public class ProductService : IProduct, IProductComment, IBaskOrderLog
    {
        protected List<Product> AllProducts
        {
            get
            {
                return CacheManager.Instance.GetObjectFromMemoryCache(CacheKey.Product) as List<Product>;
            }
        }

        public Model.Product GetProductByID(Guid id)
        {
            var product = ProductContext.Get(id);
            product.Detail = System.Web.HttpContext.Current.Server.HtmlDecode(product.Detail);
            product.Images = ProductContext.GetImages(id);
            return product;
        }

        public List<SimpleProduct> GetProductNameList()
        {
            var query = from p in AllProducts
                        select new SimpleProduct 
                        {
                            Name= p.Name,
                            PYName = ChineseToPinYin.Convert(p.Name),
                            PYChar = ChineseToPinYin.GetSpellCode(p.Name)
                        };

            return query.Distinct().ToList();
        }
        /// <summary>
        /// pageIndex>=1
        /// </summary>
        /// <param name="ProductCategoryID"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageCount"></param>
        /// <param name="sorts"></param>
        /// <returns></returns>
        public Dictionary<string, Object> GetProductListByCondition(int ProductCategoryID, int pageIndex, int pageCount, ProductSort sorts, bool isASC)
        {
            return GetProductListByConditions(pageIndex, pageCount, sorts, isASC, x => x.ProductCategoryID == ProductCategoryID);
        }

        public Dictionary<string, Object> GetProductListByName(int ProductCategoryID, int pageIndex, int pageCount, ProductSort sorts, bool isASC, string name)
        {
            Expression<Func<Product, bool>> filter = null;
            if (ProductCategoryID == SearchType.GlobalSearch)
                filter = x => x.Name.Contains(name);
            else
                filter = x => x.ProductCategoryID == ProductCategoryID && x.Name.Contains(name);
            return GetProductListByConditions(pageIndex, pageCount, sorts, isASC, filter);
        }

        public Dictionary<string, Object> GetProductListByPriceZoneAndBrand(int ProductCategoryID, int pageIndex, int pageCount, ProductSort sorts, bool isASC,
            decimal minPrice, decimal maxPrice, string brand)
        {
            Expression<Func<Product, bool>> filter = null;
            if (minPrice == 0 && maxPrice == 0)
            {
                filter = x => x.ProductCategoryID == ProductCategoryID && x.BrandName == brand;
            }
            else if (string.IsNullOrEmpty(brand))
            {
                filter = x => x.ProductCategoryID == ProductCategoryID && x.ShopPrice >= minPrice && x.ShopPrice <= maxPrice;
            }
            else
            {
                filter = x => x.ProductCategoryID == ProductCategoryID && x.ShopPrice >= minPrice && x.ShopPrice <= maxPrice && x.BrandName == brand; ;
            }

            return GetProductListByConditions(pageIndex, pageCount, sorts, isASC, filter);
        }

        private Dictionary<string, Object> GetProductListByConditions(int pageIndex, int pageCount,
            ProductSort sorts, bool isASC, Expression<Func<Product, bool>> filter)
        {
            Func<IQueryable<Product>, IOrderedQueryable<Product>> order = null;
            switch (sorts)
            {
                case ProductSort.ModifyTime:
                    if (isASC)
                        order = x => x.OrderBy(k => k.ModifyTime);
                    else
                        order = x => x.OrderByDescending(k => k.ModifyTime);
                    break;
                case ProductSort.Price:
                    if (isASC)
                        order = x => x.OrderBy(k => k.ShopPrice);
                    else
                        order = x => x.OrderByDescending(k => k.ShopPrice);
                    break;
                default:
                    if (isASC)
                        order = x => x.OrderBy(k => k.SaleNumber);
                    else
                        order = x => x.OrderByDescending(k => k.SaleNumber);
                    break;
            }
            int total = 0;
            Dictionary<string, Object> dic = new Dictionary<string, object>();
            var allProducts = CacheManager.Instance.GetObjectFromMemoryCache(CacheKey.Product) as List<Product>;
            var data = ProductContext.GetByPage(allProducts, pageIndex, pageCount, filter, order, out total);
            var properties = CacheManager.Instance.GetObjectFromMemoryCache(CacheKey.ProductProperty) as List<ProductProperty>;
            foreach (var product in data)
            {
                product.Detail = System.Web.HttpContext.Current.Server.HtmlDecode(product.Detail);
                product.ProductProperty = properties.Where(x => x.ProdGuid == product.Guid).ToList();
            }
            dic.Add(PagerConst.Count, total);
            dic.Add(PagerConst.Data, data);
            return dic;
        }

        public Dictionary<string, Object> GetProductCommentList(int startPage, int pageSize, Guid productID)
        {
            int total = 0;
            Dictionary<string, Object> dic = new Dictionary<string, object>();
            var allComments = CacheManager.Instance.GetObjectFromMemoryCache(CacheKey.ProductComment) as List<ProductComment>;
            var comments = allComments.Where(x => x.ProductGuid == productID).ToList();
            var data = ProductCommentContext.GetByPage(comments, startPage, pageSize, null,
                x => x.OrderByDescending(k => k.SendTime), out total);
            dic.Add(PagerConst.Count, comments.Count);
            dic.Add(PagerConst.Data, data);
            return dic;
        }

        public void AddBaskOrderLog(BaskOrderLog coment)
        {
            BaskOrderLogContext.Add(coment);
        }

        public Dictionary<string, Object> GetBaskOrderLogs(int startPage, int pageSize, Guid productID)
        {
            var baskOrderLogs = CacheManager.Instance.GetObjectFromMemoryCache(CacheKey.BaskOrderLog) as List<BaskOrderLog>;
            int total = 0;
            List<BaskOrderLog> returnData = BaskOrderLogContext.GetByPage(baskOrderLogs, startPage, pageSize, x => x.ProductGuid == productID, t => t.OrderBy(x => x.CreateTime), out total);
            Dictionary<string, Object> dic = new Dictionary<string, object>();
            dic.Add(PagerConst.Data, returnData);
            dic.Add(PagerConst.Count, total);
            return dic;
        }

        public BaskOrderLogAndComments GetBaskOrderLogAndComments(Guid id)
        {
            return BaskOrderLogContext.GetBaskOrderLogAndComments(id).FirstOrDefault();
        }



        public List<ProductAttribute> GetProductAttribute(Guid productGuid)
        {
            return ProductAttributeContext.GetByConditions(t => t.ProductGuid == productGuid);
        }
    }
}
